package com.cqndt.disaster.device.sms.service.impl;

import com.cqndt.disaster.device.common.util.SudasSmsUtil;
import com.cqndt.disaster.device.dao.*;
import com.cqndt.disaster.device.domain.TabProject;
import com.cqndt.disaster.device.domain.TabUser;
import com.cqndt.disaster.device.sms.service.LonAndLatService;
import com.cqndt.disaster.device.vo.TabMsgRecord;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Create by Intellij IDEA
 *
 * @User : ningjunhao
 * @Mail : 15823526611@139.com
 * @Time : 2019-08-05 10:01
 **/
@Service
public class LonAndLatServiceImpl implements LonAndLatService {

    @Autowired
    TabProjectMapper tabProjectMapper;

    @Autowired
    TabMonitorMapper tabMonitorMapper;

    @Autowired
    TabDeviceMapper tabDeviceMapper;

    @Autowired
    TabUserMapper tabUserMapper;
    @Autowired
    TabMsgRecordMapper tabMsgRecordMapper;
    @Override
    public List<Map<String,Object>> fsLonAndLat(int userId,String[] lonLat) {
        //用给定的x和y坐标来创建一个Point2D对象
        List<Point2D.Double> pts = new ArrayList<Point2D.Double>();
        for(int i=0;i<lonLat.length;i++){
            double x = Double.parseDouble(lonLat[i]);
            i+=1;
            double y = Double.parseDouble(lonLat[i]);
            pts.add(new Point2D.Double(x,y));
        }

        //获取所有项目
        List<TabProject> projectList = tabProjectMapper.getProjectAll(userId);
        //框选范围内项目id
        List<Integer> projectId = new ArrayList<>();
        //判断是否在经纬度内并把结果为true的项目id存入projectId
        for(TabProject project : projectList){
            double lon = Double.parseDouble(project.getLongitude().toString());
            double lat = Double.parseDouble(project.getLatitude().toString());
            Point2D.Double point = new Point2D.Double(lon, lat);
            if(IsPtInPoly(point, pts)){
                //点在框选范围内
                projectId.add(project.getId());
            }
        }

        //如果框选范围内没有项目，返回null
        if(projectId.isEmpty()){
            return  null;
        }

        //获取框选范围内所有项目
        List<Map<String ,Object>> projects = tabProjectMapper.getProjectByIds(projectId);
        for(Map<String,Object> project : projects){
            Integer id = Integer.valueOf(project.get("id").toString());
            //二级类型
            List<Map<String, Object>> mapLists = tabMonitorMapper.getDeviceByProjectId(id);
            for(Map<String,Object> map : mapLists){
                map.put("project_name",map.get("device_name"));
            }
            project.put("cityResults", mapLists);
        }
        return projects;
    }

    @Override
    public List<Map<String, Object>> findPersion(String deviceId) {
        String[] split = deviceId.split(",");
        List<String> list = new ArrayList<>();
        for (String s : split) {
            list.add(s);
        }
        List<Map<String,Object>> map = tabDeviceMapper.getMonitorPersionByDeviceId(list);
        return map;
    }
//发送短信并把记录存入tab_msg_record表
    @Override
    public boolean sendSms(String mobile,String content,int userId) {
        TabUser user = tabUserMapper.selectByPrimaryKey(userId);
        boolean state = true;
        if (SudasSmsUtil.send(mobile,content)){
        }else {
            state = false;
        }
        Date today = new Date();
        if(mobile.length()>11){
            String[] phoneArr = mobile.split(",");
            for(int i=0;i<phoneArr.length;i++){
                String phone = phoneArr[i];

                TabMsgRecord tabMsgRecord=new TabMsgRecord();
                tabMsgRecord.setSendPerson(user.getUserName());
                tabMsgRecord.setSendTime(today);
                tabMsgRecord.setPhone(phone);
                tabMsgRecord.setContent(content);
                if (state){
                    tabMsgRecord.setSendState(1);
                }else {
                    tabMsgRecord.setSendState(0);
                }
                tabMsgRecord.setSendWay(0);
                tabMsgRecordMapper.addTabMsgRecord(tabMsgRecord);
            }
        }else {
            TabMsgRecord tabMsgRecord=new TabMsgRecord();
            tabMsgRecord.setSendPerson(user.getUserName());
            tabMsgRecord.setSendTime(today);
            tabMsgRecord.setPhone(mobile);
            tabMsgRecord.setContent(content);
            if (state){
                tabMsgRecord.setSendState(1);
            }else {
                tabMsgRecord.setSendState(0);
            }
            tabMsgRecord.setSendWay(1);
            tabMsgRecordMapper.addTabMsgRecord(tabMsgRecord);
        }
        return state;
    }

    //判断项目是否在框选经纬度里面
    private boolean IsPtInPoly(Point2D.Double point, List<Point2D.Double> pts){
        int N = pts.size();
        boolean boundOrVertex = true; //如果点位于多边形的顶点或边上，也算做点在多边形内，直接返回true
        int intersectCount = 0;//cross points count of x
        double precision = 2e-10; //浮点类型计算时候与0比较时候的容差
        Point2D.Double p1, p2;//neighbour bound vertices
        Point2D.Double p = point; //当前点

        p1 = pts.get(0);//left vertex
        for(int i = 1; i <= N; ++i){//check all rays
            if(p.equals(p1)){
                return boundOrVertex;//p is an vertex
            }

            p2 = pts.get(i % N);//right vertex
            if(p.x < Math.min(p1.x, p2.x) || p.x > Math.max(p1.x, p2.x)){//ray is outside of our interests
                p1 = p2;
                continue;//next ray left point
            }

            if(p.x > Math.min(p1.x, p2.x) && p.x < Math.max(p1.x, p2.x)){//ray is crossing over by the algorithm (common part of)
                if(p.y <= Math.max(p1.y, p2.y)){//x is before of ray
                    if(p1.x == p2.x && p.y >= Math.min(p1.y, p2.y)){//overlies on a horizontal ray
                        return boundOrVertex;
                    }

                    if(p1.y == p2.y){//ray is vertical
                        if(p1.y == p.y){//overlies on a vertical ray
                            return boundOrVertex;
                        }else{//before ray
                            ++intersectCount;
                        }
                    }else{//cross point on the left side
                        double xinters = (p.x - p1.x) * (p2.y - p1.y) / (p2.x - p1.x) + p1.y;//cross point of y
                        if(Math.abs(p.y - xinters) < precision){//overlies on a ray
                            return boundOrVertex;
                        }

                        if(p.y < xinters){//before ray
                            ++intersectCount;
                        }
                    }
                }
            }else{//special case when ray is crossing through the vertex
                if(p.x == p2.x && p.y <= p2.y){//p crossing over p2
                    Point2D.Double p3 = pts.get((i+1) % N); //next vertex
                    if(p.x >= Math.min(p1.x, p3.x) && p.x <= Math.max(p1.x, p3.x)){//p.x lies between p1.x & p3.x
                        ++intersectCount;
                    }else{
                        intersectCount += 2;
                    }
                }
            }
            p1 = p2;//next ray left point
        }

        if(intersectCount % 2 == 0){//偶数在多边形外
            return false;
        } else { //奇数在多边形内
            return true;
        }
    }
}
